package com.witmore.skyline.web.service;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.witmore.skyline.web.service.third.yjx.dto.DeviceOilDTO;
import lombok.Getter;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 对应 JS 的 get_oil_percent
 */
public class OilAnalyzer {

    /**
     * 中间点信息，对应 JS 中 dot_21_arr / dot_14_arr 每一行数组
     * JS 数组含义大致为：
     * [0] level1   -> level
     * [1] dot_type -> dotType
     * [2] idx      -> index
     * [3] level2   -> matchLevel
     * [4] dt2      -> matchDotType
     * [5] j        -> matchIndex
     * [6] time2    -> matchTime
     */
    @Getter
    public static class DotRecord {
        double level;
        int dotType;
        int index;
        String time;

        // 和 12 / 41 匹配到的点
        Double matchLevel;
        Integer matchDotType;
        Integer matchIndex;
        String matchTime;
    }

    /**
     * 对应 JS 里 upDataList 中每一个对象
     */
    @Getter
    public static class OilRefuelInfo {
        double oilCharge;   // 加油量
        String addOilTime;  // 开始时间
        LocalDateTime addOilTimeL;

    }

    /**
     * 对应 JS 里的 detail 对象
     */
    @Getter
    public static class OilDetail {
        @JsonIgnore
        List<DotRecord> dot21List;
        List<OilRefuelInfo> upDataList;
        double upTotal;
        int upTimes;

        @JsonIgnore
        List<DotRecord> dot14List;
        double downTotal;
        int downTimes;
    }

    public static OilDetail getOilPercent(List<DeviceOilDTO> result) {
        List<DotRecord> dotTypeList = new ArrayList<>();
        List<DotRecord> dot21List = new ArrayList<>();
        List<DotRecord> dot14List = new ArrayList<>();

        // 相当于 JS 的第一段 for (result)
        for (int i = 0; i < result.size(); i++) {
            DeviceOilDTO el = result.get(i);
            int dotType = 0;

            if (i >= 1 && i < result.size() - 1) {
                double a = Double.parseDouble(result.get(i - 1).getOilLevel());
                double b = Double.parseDouble(result.get(i).getOilLevel());
                double c = Double.parseDouble(result.get(i + 1).getOilLevel());
                // 这里的 getDotType 需要你自己按 JS 版本实现
                dotType = getDotType(a, b, c);
            }

            // 所有点的数组 dot_type_arr
            DotRecord allRecord = new DotRecord();
            allRecord.level = Double.parseDouble(el.getOilLevel());
            allRecord.dotType = dotType;
            allRecord.index = i;
            allRecord.time = el.getTime();
            dotTypeList.add(allRecord);

            // dot_21_arr
            if (dotType == 21) {
                DotRecord r = new DotRecord();
                r.level = allRecord.level;
                r.dotType = allRecord.dotType;
                r.index = allRecord.index;
                r.time = allRecord.time;
                dot21List.add(r);
            }

            // dot_14_arr
            if (dotType == 14) {
                DotRecord r = new DotRecord();
                r.level = allRecord.level;
                r.dotType = allRecord.dotType;
                r.index = allRecord.index;
                r.time = allRecord.time;
                dot14List.add(r);
            }
        }

        // ========== up 部分（处理 dot_21_arr） ==========
        // 找到每个 21 点对应之前最近的 12 点
        for (DotRecord d21 : dot21List) {
            int idx1 = d21.index;
            for (int j = idx1; j > 0; j--) {
                DotRecord d2 = dotTypeList.get(j);
                if (d2.dotType == 12) {
                    d21.matchLevel = d2.level;
                    d21.matchDotType = d2.dotType;
                    d21.matchIndex = j;
                    d21.matchTime = d2.time;
                    break;
                }
            }
        }

        List<OilRefuelInfo> upDataList = new ArrayList<>();
        double upTotal = 0.0;
        int upTimes = 0;

        // 计算 up_total、up_times、upDataList
        for (DotRecord d21 : dot21List) {
            if (d21.matchLevel == null) {
                continue;
            }
            double up = d21.level - d21.matchLevel;
            if (up > 5) {
                upTotal += up;
                upTimes++;

                OilRefuelInfo info = new OilRefuelInfo();
                info.oilCharge = up;
                // JS 里 addOilTime 用的是 dot_21_one[6]，即 matchTime
                info.addOilTime = d21.matchTime;
                info.addOilTimeL = stringConvertDateTime(info.addOilTime);
                upDataList.add(info);
            }
        }

        // ========== down 部分（处理 dot_14_arr） ==========
        // 找到每个 14 点对应之后最近的 41 点
        for (DotRecord d14 : dot14List) {
            int idx1 = d14.index;
            for (int j = idx1; j < dotTypeList.size(); j++) {
                DotRecord d2 = dotTypeList.get(j);
                if (d2.dotType == 41) {
                    d14.matchLevel = d2.level;
                    d14.matchDotType = d2.dotType;
                    d14.matchIndex = j;
                    d14.matchTime = d2.time;
                    break;
                }
            }
        }

        double downTotal = 0.0;
        int downTimes = 0;
        for (DotRecord d14 : dot14List) {
            if (d14.matchLevel == null) {
                continue;
            }
            double down = d14.level - d14.matchLevel;
            if (down > 5) {
                downTotal += down;
                downTimes++;
            }
        }

        // 组装返回结果，相当于 JS 的 detail 对象
        OilDetail detail = new OilDetail();
        detail.dot21List = dot21List;
        detail.upDataList = upDataList;
        detail.upTotal = upTotal;
        detail.upTimes = upTimes;

        detail.dot14List = dot14List;
        detail.downTotal = downTotal;
        detail.downTimes = downTimes;

        // JS 里最后一行是 oilRefuelList.value = upDataList || []
        // 在 Java 里你可以根据需要把 detail.upDataList 传给别的地方
        return detail;
    }

    /**
     * 这里是占位方法，对应 JS 的 getDotType({ a, b, c })
     * 你可以直接把 JS 里的逻辑翻译到这里。
     */
    /**
     * 根据 3 个点获取中间点的类型
     * 对应 JS 的：
     * function getDotType({ a, b, c }) { ... }
     */
    private static int getDotType(double a, double b, double c) {
        if (a == b && b == c) {
            return 1;
        } else if (a < b && b < c) {
            return 2;
        } else if (a > b && b > c) {
            return 4;
        } else if (a < b && b > c) {
            return 3;
        } else if (a > b && b < c) {
            return 5;
        } else if (a > b && b == c) {
            return 41;
        } else if (a == b && b < c) {
            return 12;
        } else if (a < b && b == c) {
            return 21;
        } else if (a == b && b > c) {
            return 14;
        }
        return 0;
    }

    public static LocalDateTime stringConvertDateTime(String dateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(dateTime, formatter);
    }

}
